/**
 *
 */
package de.cbf.cam.dsa.facet.container.editor;

import java.beans.IndexedPropertyChangeEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.eclipse.swt.widgets.Control;

import de.cbf.cam.dsa.facet.container.FacetContainer;
import de.cbf.util.controller.ControllerEvent;
import de.cbf.util.controller.IListenerController;
import de.cbf.util.entity.facet.edit.composites.factorys.AbstractFacetSectionFactory;
import de.cbf.util.entity.facet.edit.controller.AbstractControllerEditFacet;
import de.cbf.util.ui.composites.CompositeListEdit;
import de.cbf.util.ui.controller.ControllerListEdit;
import de.cbf.util.ui.listener.IUiChangeListener;
import de.cbf.util.ui.listener.UiChangeEvent;

/**
 * @author Nebelritter
 *
 */
public class ControllerEditorFacetContainer extends AbstractControllerEditFacet<FacetContainer> {
	private static final Log logger = LogFactory.getLog(ControllerEditorFacetContainer.class);

	public static final String TEXT_STATE_EVENT_Volume_ERROR	= "Volume setting not correct";
	public static final String TEXT_STATE_EVENT_Volume_WARNING	= FacetContainer.TEXT_UNSET_Volume;
	public static final String TEXT_STATE_EVENT_ForTypes_ERROR	= "ForTypes setting not correct";
	public static final String TEXT_STATE_EVENT_ForTypes_WARNING	= FacetContainer.TEXT_UNSET_ForTypes;
	
	protected static StateEvent STATE_EVENT_Volume_ERROR 		= new StateEvent(TEXT_STATE_EVENT_Volume_ERROR, StateEvent.STATE_ERROR); 	
	protected static StateEvent STATE_EVENT_Volume_WARNING		= new StateEvent(TEXT_STATE_EVENT_Volume_WARNING, StateEvent.STATE_WARNING);
	protected static StateEvent STATE_EVENT_ForTypes_ERROR 		= new StateEvent(TEXT_STATE_EVENT_ForTypes_ERROR, StateEvent.STATE_ERROR); 	
	protected static StateEvent STATE_EVENT_ForTypes_WARNING	= new StateEvent(TEXT_STATE_EVENT_ForTypes_WARNING, StateEvent.STATE_WARNING); 
	
	
	protected CompositeEditContainer 	compositeEditContainer;

	protected ControllerListEdit		controllerForTypesEdit;
	/**
	 *
	 */
	public ControllerEditorFacetContainer() {
		super();
	}

	@Override
	protected void init() {
		super.init();
		pclFacetContainer = new PCLFacetContainer();
		uilFacetContainer = new UILFacetContainer();
	}

	@Override
	protected AbstractFacetSectionFactory createSectionFactory() {
		return new SectionFactoryContainer();
	}

	@Override
	protected FacetContainer createNewFacet() {
		FacetContainer facet = new FacetContainer();
		return facet;
	}

	@Override
	public Class<FacetContainer> getFacetClass() {
		return FacetContainer.class;
	}

	
	public void modifyVolume(String newVolume) {	
		if(facet == null) return;	
		facet.setVolume(newVolume);		
	}
		
	public void modifyForTypes(List<String> newForTypes) {
		if(facet == null) return;	
		facet.setForTypes(newForTypes);				
	}
	
	public void updateVolume(String newVolume) {
		if(newVolume != null && compositeEditContainer != null){
			if( ! newVolume.equals(FacetContainer.UNSET_VOLUME)){				
				compositeEditContainer.setVolume(newVolume);
				removeStateEvent(STATE_EVENT_Volume_WARNING);
			}else{
				compositeEditContainer.setVolume("");
				addStateEvent(STATE_EVENT_Volume_WARNING);
			}				
		}			
	}	
	
	public void updateForTypes(List<String> newForTypes) {
		if(controllerForTypesEdit != null){
			controllerForTypesEdit.setList(newForTypes);
		}				
	}
		
	@Override
	protected void updateAll(FacetContainer facet) {
		if(facet != null){
			updateVolume(facet.getVolume());
			updateForTypes(facet.getForTypes());
		}else{
			updateClearUI();
		}		
	}
	
	@Override
	protected void updateClearUI() {
		updateVolume(FacetContainer.UNSET_VOLUME);
		updateForTypes(FacetContainer.UNSET_ForTypes);		
	}
	
	protected ControllerListEdit getSubControllerForTypesInstance(){
		if(controllerForTypesEdit == null){
			controllerForTypesEdit = new ControllerEditForTypes();
			controllerForTypesEdit.registerEventListener(celForTypes);
		}
		return controllerForTypesEdit;
	}
	
	@Override
	protected void preSetSection() {
		super.preSetSection();
		if(section != null){
			Control client = section.getClient();
			if (client instanceof CompositeEditContainer) {
				compositeEditContainer = (CompositeEditContainer) client;
				deRegisterUIListeners(compositeEditContainer);
				
			}else{
				logger.error("wrong client in section: expected "+CompositeEditContainer.class.getSimpleName()+
						" got: "+client.getClass().getSimpleName());
			}
		}
	}

	@Override
	protected void postSetSection() {
		super.postSetSection();
		Control client = section.getClient();
		if (client instanceof CompositeEditContainer) {
			compositeEditContainer = (CompositeEditContainer) client;
			registerUIListeners(compositeEditContainer);
		}else{
			logger.error("wrong client in section: expected "+CompositeEditContainer.class.getSimpleName()+
					" got: "+client.getClass().getSimpleName());
		}
	}

	protected void registerUIListeners(CompositeEditContainer compositeCategory) {
		compositeCategory.registerUIListener(uilFacetContainer);
		CompositeListEdit cp_ForTypes = compositeCategory.getCompositeForTypes();
		if(cp_ForTypes != null){
			ControllerListEdit subControllerForTypes = getSubControllerForTypesInstance();
			subControllerForTypes.setComposite(cp_ForTypes);
		}
	}

	protected void deRegisterUIListeners(CompositeEditContainer compositeCategory) {
		compositeCategory.deRegisterUIListener(uilFacetContainer);
		if(controllerForTypesEdit != null){
			controllerForTypesEdit.setComposite(null);
		}
	}

	@Override
	protected void preSetNewFacet() {
		super.preSetNewFacet();
		if(facet != null){
			deRegisterModelListeners(facet);
		}
	}

	@Override
	protected void postSetNewFacet() {
		super.postSetNewFacet();
		if(facet != null){
			registerModelListeners(facet);
		}
	}

	protected void registerModelListeners(FacetContainer facet) {
		facet.getPropertyChangeSupport().addPropertyChangeListener(pclFacetContainer);
		ControllerListEdit subControllerForTypes = getSubControllerForTypesInstance();
		subControllerForTypes.setList(facet.getForTypes());
	}

	protected void deRegisterModelListeners(FacetContainer facet) {
		facet.getPropertyChangeSupport().removePropertyChangeListener(pclFacetContainer);
		if (controllerForTypesEdit != null) {
			controllerForTypesEdit.setList(new ArrayList<String>());			
		}
	}

	protected UILFacetContainer uilFacetContainer;
	protected class UILFacetContainer implements IUiChangeListener{
		@Override
		public void uiChanged(UiChangeEvent event) {
			int index = event.getIndex();
			switch (index) {
				case CompositeEditContainer.EVT_EDIT_VOLUME:{
					Object obj = event.getNewValue();
					if (obj instanceof String) {
						String volume = (String) obj;
						modifyVolume(volume);
					}
					break;
				}
				default:
					break;
			}
		}

		@Override
		public void commandIssued(int index, Object... parameters) {
			//not used
		}
	}

	protected PCLFacetContainer pclFacetContainer;
	protected class PCLFacetContainer implements PropertyChangeListener{

		@Override
		public void propertyChange(PropertyChangeEvent evt) {
			if (evt instanceof IndexedPropertyChangeEvent) {
				IndexedPropertyChangeEvent idxEvt = (IndexedPropertyChangeEvent) evt;
				switch (idxEvt.getIndex()) {
					case FacetContainer.PI_VOLUME:{
						if (idxEvt.getNewValue() instanceof String) {
							String volume = (String) idxEvt.getNewValue();
							updateVolume(volume);
						}
						break;
					}
					case FacetContainer.PI_FOR_TYPES:{
						if (idxEvt.getNewValue() instanceof List) {
							List<?> list = (List<?>) idxEvt.getNewValue();							
							List<String> resultList = new ArrayList<String>();
							for (Object obj : list) {
								if (obj instanceof String) {
									String string = (String) obj;
									resultList.add(string);
								}
							}							
							updateForTypes(resultList);
						}
						break;
					}
					default:
						break;
				}
			}
		}
	}
	
	protected CELForTypes celForTypes = new CELForTypes();
	protected class CELForTypes implements IListenerController{
		@Override
		public int handleControllerEvent(ControllerEvent event) {
			String code = event.getEventCode();
			if(ControllerListEdit.CTRL_EVT_CODE_LIST_UPDATED.equals(code)){
				List<Object> parameters = event.getParameters();
				for (Object object : parameters) {
					if (object instanceof List) {
						List<?> list = (List<?>) object;
						List<String> resultList = new ArrayList<String>();
						for (Object obj : list) {
							if (obj instanceof String) {
								String string = (String) obj;
								resultList.add(string);
							}
						}
						modifyForTypes(resultList);
					}
				}
				return RETURN_HANDLED;
			}			
			return RETURN_PROPAGATED;
		}
	}
	
	
	
}
